/******************************
 * 订阅发布模式
******************************/
let _events = {}

/** 
 * 监听event事件，触发时调用callback函数
 * @param event {String} 订阅事件名称
 * @param callback {Function} 订阅事件方法
 */
const on = (event: string, callback: (...any) => any) => {
	let callbacks = _events[event] || []
	callbacks.push(callback)
	_events[event] = callbacks
}

/** 
 * 停止监听event事件
 * @param event {String} 停止订阅事件名称
 * @param callback {Function} 停止订阅事件方法，不填则停止订阅该事件的所有方法
 */
const off = (event: string, callback?: (...any) => any) => {
	_events[event] = []

	if (!event) {
		_events = {}
	} else if (!_events.hasOwnProperty(event)) {
		console.error(event + '：事件未注册')
	} else if (!callback) {
		_events[event] = []
	} else {
		_events[event].forEach((item, key, arr) => {
			if (item === callback) {
				arr.splice(key, 1);
			}
		})
	}
}

/** 
 * 触发事件，并把参数传给事件的处理函数
 */
const emit = (event: string, ...args: any[]) => {
	const callbacks = _events[event]
	!callbacks ?
		console.error(event + '：该方法未绑定') :
		callbacks.forEach(fn => fn(...args))
}

/** 
 * 为事件注册单次监听器
 */
const once = (event: string, callback: (...any) => any) => {
	let wrapFanc = (...args) => {
		callback.apply(this, args)
		off(event)
	}
	on(event, wrapFanc)
}


let api = { on, off, emit, once }
window['_'] = Object.assign(window['_'] || {}, api)
export default api